home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 3 / Amiga Tools 3.iso / audio / jukebox-extensions / source / catviewer.c next >
C/C++ Source or Header  |  1995-08-25  |  13KB  |  535 lines

  1. /* JB-CatViewer -- soll die JukeBox Katalogdateien komfortabler anzeigen */
  2.  
  3. /* INCLUDE */
  4.  
  5. #include <exec/lists.h>
  6. #include <exec/memory.h>
  7. #include <intuition/intuition.h>
  8. #include <libraries/gadtools.h>
  9. #include <clib/alib_protos.h>
  10. #if defined(_DCC)
  11.   #include <clib/intuition_protos.h>
  12.   #include <clib/graphics_protos.h>
  13.   #include <clib/gadtools_protos.h>
  14.   #include <clib/exec_protos.h>
  15.   #include <clib/dos_protos.h>
  16. #else
  17.   #include <proto/intuition.h>
  18.   #include <proto/graphics.h>
  19.   #if defined(__GNUC__)
  20.     #define GT_SetGadgetAttrsA _GT_SetGadgetAttrsA
  21.   #endif
  22.   #include <proto/gadtools.h>
  23.   #if defined(__GNUC__)
  24.     #undef GT_SetGadgetAttrsA
  25.   #endif
  26.   #include <proto/exec.h>
  27.   #include <proto/dos.h>
  28. #endif
  29. #include <string.h>
  30.  
  31. struct VolNode {
  32.    struct Node    ExecNode;
  33.    UBYTE          Pad[2];
  34.    struct MinList TitleHeader;
  35.  };
  36.  
  37. struct FindPara {
  38.    BYTE Success,Pad[3];
  39.    LONG Position;
  40.  };
  41.  
  42. /* P R O T O T Y P E N */
  43.  
  44. void AdjustGadgets(void);
  45. int MakeGadgets(void);
  46. void RemoveGadgets(void);
  47. int MakeLists(void);
  48. void CatchNextString(char *,LONG,struct FindPara *);
  49. struct VolNode *MakeVolNode(char *);
  50. struct Node *MakeNode(char *);
  51. struct MinList *TitleHeaderOfNthVolNode(int);
  52. void FindStr(char *,char *,struct FindPara *);
  53. int CompareFrag(char *,char *);
  54. void ShowMsg(STRPTR);
  55.  
  56. /*
  57. ** NewList als Makro
  58. */
  59. /*
  60. #define NEWLIST(l) ((l)->lh_Head = (struct Node *)&(l)->lh_Tail, \
  61.                     (l)->lh_Tail = NULL, \
  62.                     (l)->lh_TailPred = (struct Node *)&(l)->lh_Head)
  63. */ /* deaktiviert, benutzt amiga.lib NewList! */
  64.  
  65. #define NOTHINGFOUND 0
  66. #define STRINGFOUND  1
  67. #define CROSSFOUND   2
  68.  
  69. #define POOLSIZE     4096
  70. #define TRESHSIZE    1024
  71.  
  72. #define DEFAULTIN  "musiccatalog.cat"
  73. #define DEFAULTLEFT "CDs"
  74. #define DEFAULTRIGHT "Inhalt"
  75. #define NOMEM        "Not enough memory!\n"
  76.  
  77. /* Globale Variablen und Strukturen */
  78.  
  79. const char VERSION[]="$VER: JukeBox-CatView V1.02 by P. Kursawe 1995";
  80.  
  81. /* libnix specials */
  82.  
  83. int __nocommandline = 1;
  84. int __initlibraries = 1;
  85.  
  86. struct TagItem gg1tags[]={GTLV_Labels,0,GTLV_ShowSelected,TAG_DONE,0};
  87. struct TagItem gg2tags[]={GTLV_Labels,0,GTLV_ReadOnly,TRUE,TAG_DONE,0};
  88.  
  89. struct GfxBase *GfxBase = NULL;
  90. struct IntuitionBase *IntuitionBase = NULL;
  91. struct Library *GadToolsBase=NULL;
  92. struct DosLibrary *DOSBase= NULL;
  93. struct Gadget *gg1ptr = NULL;
  94. struct Gadget *gg2ptr = NULL;
  95. struct Gadget *glistptr = NULL;
  96. struct Gadget *context = NULL;
  97. struct VisualInfo *vi = NULL;
  98. struct Gadget *dummygg = NULL;
  99. struct Window *mywindow = NULL;
  100. struct MinList Header;
  101. APTR mempool;
  102. struct RDArgs *rdargs = NULL;
  103. ULONG Kommandoparameter[] = {
  104.                  (ULONG)DEFAULTIN,
  105.                  (ULONG)DEFAULTLEFT,
  106.                  (ULONG)DEFAULTRIGHT
  107.                  };
  108.  
  109. struct NewGadget gadget1=
  110.             {
  111.              5,15,200,150,NULL,0,1,PLACETEXT_BELOW,0,0
  112.             };
  113. struct NewGadget gadget2=
  114.             {
  115.              210,15,200,150,NULL,0,2,PLACETEXT_BELOW,0,0
  116.             };
  117.  
  118. int _main()
  119. {
  120.  static struct TagItem wintags[]=
  121.                 {
  122.                  WA_Flags,WFLG_SIZEGADGET|WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|WFLG_ACTIVATE,
  123.                  WA_Left,0,
  124.                  WA_Top,15,
  125.                  WA_MinWidth,100,
  126.                  WA_MinHeight,70,
  127.                  WA_MaxWidth,-1,
  128.                  WA_MaxHeight,-1,
  129.                  WA_Title,(ULONG)"JukeBox Catalog Viewer",
  130.                  WA_Width,640,
  131.                  WA_Height,184,
  132.                  WA_IDCMP,IDCMP_CLOSEWINDOW|LISTVIEWIDCMP|IDCMP_NEWSIZE,
  133.                  TAG_DONE,0
  134.                 };
  135.  struct IntuiMessage *imsg;
  136.  struct Gadget *address;
  137.  ULONG imClass;
  138.  UWORD imCode;
  139.  
  140.  if((mempool=LibCreatePool(MEMF_CLEAR,POOLSIZE,TRESHSIZE)) == NULL)
  141.   return;
  142.  
  143.  NewList((struct List *)&Header);
  144.  
  145.  if((DOSBase=(struct DosLibrary*)OpenLibrary("dos.library",37L)))
  146.   {
  147.    if((GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L)))
  148.     {
  149.      if((IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37L)))
  150.       {
  151.        if((GadToolsBase=OpenLibrary("gadtools.library",37L)))
  152.     {
  153.      /* hier sind alle Libraries offen */
  154.      rdargs=ReadArgs("INFILE,LEFTTEXT,RIGHTTEXT",Kommandoparameter,NULL);
  155.      gadget1.ng_GadgetText=(UBYTE *)Kommandoparameter[1];
  156.      gadget2.ng_GadgetText=(UBYTE *)Kommandoparameter[2];
  157.      if((mywindow=OpenWindowTagList(NULL,wintags)))
  158.       {
  159.        AdjustGadgets();
  160.        if((MakeLists()))
  161.         {
  162.           if((MakeGadgets()))
  163.           {
  164.            for(;;)
  165.         {
  166.          if(Wait(1L<<mywindow->UserPort->mp_SigBit|SIGBREAKF_CTRL_C)&SIGBREAKF_CTRL_C)
  167.           break;
  168.          while((imsg=GT_GetIMsg(mywindow->UserPort)) != NULL)
  169.           {
  170.            imClass = imsg->Class;
  171.            imCode  = imsg->Code;
  172.            address = imsg->IAddress;
  173.            GT_ReplyIMsg(imsg);
  174.            switch(imClass)
  175.             {
  176.              case IDCMP_CLOSEWINDOW:
  177.               goto ende;
  178.              case IDCMP_GADGETUP:
  179.               if(address->GadgetID==1)
  180.                {
  181.                 gg2tags[0].ti_Data=(ULONG)TitleHeaderOfNthVolNode(imCode);
  182.                 GT_SetGadgetAttrsA(gg2ptr,mywindow,NULL,gg2tags);
  183.                }
  184.               break;
  185.              case IDCMP_NEWSIZE:
  186.               RemoveGadgets();
  187.               AdjustGadgets();
  188.               MakeGadgets();
  189.              default:
  190.               break;
  191.             }
  192.           }
  193.         }
  194.     ende:
  195.            RemoveGadgets();
  196.           }
  197.          else
  198.           {
  199.            ShowMsg("Could not allocate Gadgets.\n");
  200.           }
  201.          }
  202.         else
  203.         {
  204.          ShowMsg("Could not build lists\n");
  205.         }
  206.        CloseWindow(mywindow);
  207.       }
  208.       FreeArgs(rdargs);
  209.      /* alle Libraries schließen */
  210.      CloseLibrary(GadToolsBase);
  211.     }
  212.        else
  213.         {
  214.          ShowMsg("Can't open gadtools.library V37.\n");
  215.         }
  216.        CloseLibrary((struct Library *)IntuitionBase);
  217.       }
  218.      else
  219.       {
  220.        ShowMsg("Can't open intuition.library V37.\n");
  221.       }
  222.      CloseLibrary((struct Library *)GfxBase);
  223.     }
  224.    else
  225.     {
  226.      ShowMsg("Can't open graphics.library V37.\n");
  227.     }
  228.    CloseLibrary((struct Library *)DOSBase);
  229.   } 
  230.   LibDeletePool(mempool);
  231.  return 0;
  232. }
  233.  
  234. /* -------------------------------------- */
  235. /*            UNTERROUTINEN               */
  236. /* -------------------------------------- */
  237.  
  238. void AdjustGadgets(void)
  239.  {
  240.   gadget1.ng_LeftEdge = mywindow->BorderLeft+5;
  241.   gadget1.ng_TopEdge  = mywindow->BorderTop+5;
  242.   gadget1.ng_Height   = mywindow->Height - mywindow->BorderBottom - 15 - gadget1.ng_TopEdge;
  243.   if(gadget1.ng_Height < 5)
  244.    {
  245.     gadget1.ng_Height = 5;
  246.    }
  247.   gadget2.ng_Height = gadget1.ng_Height;
  248.   gadget1.ng_Width    = ( (mywindow->Width - mywindow->BorderLeft - mywindow-> BorderRight - 15) / 2);
  249.    if(gadget1.ng_Width < 10)
  250.     {
  251.      gadget1.ng_Width = 10;
  252.     }
  253.   gadget2.ng_LeftEdge = gadget1.ng_Width + gadget1.ng_LeftEdge + 5;
  254.   gadget2.ng_TopEdge  = gadget1.ng_TopEdge;
  255.   gadget2.ng_Height   = gadget1.ng_Height;
  256.   gadget2.ng_Width    = gadget1.ng_Width;
  257.  }
  258.  
  259. /* Muß hier Gadgets belegen und einbinden. */
  260.  
  261. int MakeGadgets(void)
  262.  {
  263.  
  264.   int ret=FALSE;
  265.  
  266.   if((vi=GetVisualInfoA(mywindow->WScreen,NULL)))
  267.    {
  268.  
  269.     gadget1.ng_VisualInfo = vi;
  270.     gadget2.ng_VisualInfo = vi;
  271.  
  272.     if((dummygg=CreateContext(&glistptr)))
  273.      {
  274.       if((gg1ptr=CreateGadgetA(LISTVIEW_KIND,dummygg,&gadget1,gg1tags)))
  275.        {
  276.     if((gg2ptr=CreateGadgetA(LISTVIEW_KIND,gg1ptr,&gadget2,gg2tags)))
  277.      {
  278.       ret=TRUE;
  279.       EraseRect(mywindow->RPort,mywindow->BorderLeft,mywindow->BorderTop,mywindow->Width-mywindow->BorderRight-1,mywindow->Height-mywindow->BorderBottom-1);
  280.       AddGList(mywindow,glistptr,-1,-1,0);
  281.       RefreshWindowFrame(mywindow);
  282.       GT_RefreshWindow(mywindow,0);
  283.      }
  284.     else
  285.      {
  286.       FreeGadgets(glistptr);
  287.       glistptr = NULL;
  288.      }
  289.        }
  290.      }
  291.     else
  292.      {
  293.       FreeVisualInfo(vi);
  294.      }
  295.    }
  296.   return(ret);
  297.  }
  298.  
  299. void RemoveGadgets(void)
  300.  {
  301.   if((glistptr))
  302.    {
  303.     RemoveGList(mywindow,glistptr,-1);
  304.     FreeGadgets(glistptr);
  305.     FreeVisualInfo(vi);
  306.    }
  307.  }
  308.  
  309. int MakeLists(void)
  310.  {
  311.   struct FileInfoBlock *fib = NULL;
  312.   struct VolNode *voln=NULL;
  313.   struct Node *node=NULL;
  314.   struct FindPara Paras;
  315.   BPTR filehandle = NULL;
  316.   BYTE *buffer;
  317.   int ret = FALSE;
  318.   LONG pos=0;
  319.   Paras.Success = CROSSFOUND; Paras.Position = 0;
  320.  
  321.   if((fib=AllocDosObject(DOS_FIB,NULL)))
  322.    {
  323.     if((filehandle=Open((char *)Kommandoparameter[0],MODE_OLDFILE)))
  324.      {
  325.       if(DOSTRUE==ExamineFH(filehandle,fib))
  326.        {
  327.         if((buffer=LibAllocPooled(mempool,fib->fib_Size)))
  328.          {
  329.            Read(filehandle,buffer,fib->fib_Size);
  330.           /* Eigentliche Bearbeitung der Textdatei */
  331.        gg1tags[0].ti_Data=(ULONG)&Header;
  332.       while((Paras.Success != NOTHINGFOUND)&&((int)pos < (int)buffer + (int)fib->fib_Size))
  333.        {
  334.             pos=pos+Paras.Position;
  335.         switch(Paras.Success)
  336.          {
  337.           case STRINGFOUND:
  338.            pos=Paras.Position;
  339.            if((voln))
  340.             {
  341.              if((node=MakeNode(&buffer[pos])))
  342.               {
  343.                AddTail((struct List *)&voln->TitleHeader,node);
  344.               }
  345.                 }
  346.            pos=pos+strlen(&buffer[pos]);
  347.            break;
  348.           case CROSSFOUND:
  349.            pos = pos + Paras.Position;
  350.            CatchNextString(buffer,pos,&Paras);
  351.            if(Paras.Success == STRINGFOUND)
  352.             {
  353.              pos=Paras.Position;
  354.              if((voln=MakeVolNode(&buffer[pos])))
  355.               {
  356.                AddTail((struct List *)&Header,&voln->ExecNode);
  357.                ret=TRUE;
  358.               }
  359.              pos=pos+strlen(&buffer[pos]);
  360.             }
  361.            break;
  362.           default:
  363.            break;
  364.          }
  365.             CatchNextString(buffer,pos,&Paras);
  366.            }
  367.           /* fertig.... */
  368.       LibFreePooled(mempool,buffer,fib->fib_Size);
  369.          }
  370.         else
  371.          {
  372.           ShowMsg(NOMEM);
  373.          }
  374.        }
  375.       else
  376.        {
  377.         ShowMsg("Examine failed.\n");
  378.        }
  379.       Close(filehandle);
  380.      }
  381.     else
  382.      {
  383.       ShowMsg("Could not open \"");
  384.       ShowMsg((char *)Kommandoparameter[0]);
  385.       ShowMsg("\".\n");
  386.      }
  387.     FreeDosObject(DOS_FIB,fib);
  388.    }
  389.   else
  390.    {
  391.     ShowMsg("Could not allocate FileInfoBlock.\n");
  392.    }
  393.   return(ret);
  394.  }
  395.  
  396. /* Sucht einen String */
  397.  
  398. void CatchNextString(char *Puffer,LONG position,struct FindPara *parameter)
  399.  {
  400.   LONG posbak=0;
  401.   FindStr(&Puffer[position],">=\"",parameter);
  402.   if(parameter->Success == STRINGFOUND)
  403.    {
  404.     parameter->Position=parameter->Position+3;
  405.     position= position + parameter->Position;
  406.     FindStr(&Puffer[position],"\"",parameter);
  407.     if(parameter->Success != NOTHINGFOUND)
  408.      {
  409.       while(parameter->Success==CROSSFOUND)
  410.        {
  411.         posbak=parameter->Position+posbak;
  412.         FindStr(&Puffer[posbak+position],"\"",parameter);
  413.        }
  414.       Puffer[position + parameter->Position+posbak]=0;
  415.       parameter->Position=position;
  416.      }
  417.     else
  418.      {
  419.       parameter->Success=NOTHINGFOUND;
  420.      }
  421.    }
  422.  }
  423.  
  424. /* Erzeugt Nodes mit Eintrag fuer Liste der Titel */
  425.  
  426. struct VolNode *MakeVolNode(char string[])
  427.  {
  428.   struct VolNode *mem;
  429.  
  430.   if((mem=LibAllocPooled(mempool,sizeof(struct VolNode)+strlen(string)+1)))
  431.    {
  432.     mem->ExecNode.ln_Name=(char *)(mem+1);
  433.     NewList((struct List *)&mem->TitleHeader);
  434.     strcpy((char *)(mem+1),string);
  435.    }
  436.   else
  437.    {
  438.     ShowMsg(NOMEM);
  439.    }
  440.   return mem;
  441.  }
  442.  
  443. /* Erzeugt stinknormale Nodes (mit Name dahinter, natürlich! */
  444.  
  445. struct Node *MakeNode(char string[])
  446.  {
  447.   struct Node *mem;
  448.  
  449.   if((mem=LibAllocPooled(mempool,sizeof(struct Node)+strlen(string)+1)))
  450.    {
  451.     mem->ln_Name=(char *)(mem+1);
  452.     strcpy((char *)(mem+1),string);
  453.    }
  454.   else
  455.    {
  456.     ShowMsg(NOMEM);
  457.    }
  458.   return(mem);
  459.  }
  460.  
  461. /* Gibt einen Zeiger auf den TitleHeader der n-ten VolNode zurück, NULL, falls leer! */
  462.  
  463. struct MinList *TitleHeaderOfNthVolNode(int Number)
  464.  {
  465.   struct MinList *titleheader = NULL;
  466.   struct VolNode *voln = NULL;
  467.   int IsNumber = 0;
  468.   voln = (struct VolNode *)Header.mlh_Head;
  469.   for(;IsNumber < Number;IsNumber++)
  470.    {
  471.     voln = (struct VolNode *)voln->ExecNode.ln_Succ;
  472.    }
  473.   titleheader=&voln->TitleHeader;
  474.   if(titleheader->mlh_Head == NULL)
  475.    {
  476.     titleheader = NULL;
  477.    }
  478.   return(titleheader);
  479.  }
  480.  
  481. /* Suche StringB in StringA, gebe Byte des Fundes zurück oder 0. Sucht maximal 100 Bytes lang! */
  482. /* Gibt Erfolgsmeldung in der Struktur, wenn Kreuz zeigt Position 1 hinter Kreuz! */
  483.  
  484. void FindStr(char *StringA,char *StringB,struct FindPara *result)
  485.  {
  486.   LONG ret = 0;
  487.  
  488.   while(ret < 5000)
  489.    {
  490.     if(StringA[ret]=='#')
  491.      {
  492.       result->Success = CROSSFOUND;
  493.       result->Position = ret+1;
  494.       return;
  495.      }
  496.     if(StringA[ret]==StringB[0])
  497.      {
  498.       if(CompareFrag(&StringA[ret],StringB)==TRUE)
  499.        {
  500.         result->Position = ret;
  501.         result->Success = STRINGFOUND;
  502.         return;
  503.        }
  504.      }
  505.      ret++;
  506.    }
  507.    result->Success = NOTHINGFOUND;
  508.    return;
  509.  }
  510.  
  511. /* Überprüft, ob Frag der Anfang von Text ist. (Bsp: Te in Test, nicht aber Te in DerTest) */
  512.  
  513. int CompareFrag(char *Text,char *Frag)
  514.  {
  515.   LONG cnt = 0;
  516.   while(Frag[cnt] != 0)
  517.    {
  518.     if(Frag[cnt]!=Text[cnt])
  519.      {
  520.       return(FALSE);
  521.      }
  522.     cnt++;
  523.    }
  524.   return(TRUE);
  525.  }
  526.  
  527. /* gibt nur ne Meldung aus ;) */
  528.  
  529. void ShowMsg(STRPTR msg)
  530.  {
  531.   PutStr(msg);
  532.  }
  533.  
  534.  
  535.